use std::iter::FromIterator;
use std::ops::Add;

/// 类型转换用到的 From和 Into两个 trait， 它们定义了两个方法，分别是 from 和 into，这两个
/// 方法互为反操作。对于迭代器来说，并没有用到这两个 trait，但是这里值得注意的是，
/// Rust中对于trait的命名也是具有高度一致性的。
/// Rust也提供了 FromIterator和IntoIterator两个 trait，它们也互为反操作。
/// FromIterator 可以从迭代器转换为指定类型 ，而IntoIterator 可以从指定类型转换为迭代器。
pub fn start() {
    let a = [1, 2].iter().cloned().rev().collect::<Vec<_>>();
    println!("{:?}", a);

    let mut book = Book {
        name: "test".to_string(),
        isbn: 20201223,
        version: 1,
    };
    println!("{:?}", book);

    let book2 = Book { version: 2, ..book };
    println!("{:?}", book2);
    // 这种会发生错误
    // book value borrowed here after partial move
    // book.set_name("yy".to_string());

    // 这种就可以
    book.name = "yy".to_string();
    println!("{:?}", book);
}

// IntoIterator 的源码
// impl<I: Iterator> IntoIterator for I {
//     type Item = I::Item;
//     type IntoIter = I;
//
//     fn into_iter(self) -> I {
//         self
//     }
// }

// FromIterator的源码
// pub trait FromIterator<A>: Sized {
//     #[stable(feature = "rust1", since = "1.0.0")]
//     fn from_iter<T: IntoIterator<Item = A>>(iter: T) -> Self;
// }

struct Test {
    size: usize,
}

impl FromIterator<usize> for Test {
    fn from_iter<T: IntoIterator<Item = usize>>(iter: T) -> Self {
        Self {
            size: iter.into_iter().sum(),
        }
    }
}

#[derive(Debug, Clone)]
struct Book {
    name: String,
    isbn: i32,
    version: i32,
}

impl Book {
    fn set_name(&mut self, str: String) {
        self.name = str
    }
}
